package com.ushine.web.component.utils;


import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author: yls
 * @Date: 2020/10/20 11:02
 * @Description: 检测常见的sql注入和非法的字符串
 * @Version 1.0
 */
@Slf4j
public class IllegalStrFilterUtil {

    private IllegalStrFilterUtil() {
    }

    /**
     * 正则表达式
     */
    private static final String REGX = "!|！|@|◎|#|＃|(\\$)|￥|%|％|(\\^)|……|(\\&)|※|(\\*)|×|(\\()|（|(\\))|）|_|——|(\\+)|＋|(\\|)|§ ";

    /**
     * sql 关键字集合
     */
    private static final List<String> sqlList = new ArrayList<>(10);

    static {
        sqlList.add("DELETE");
        sqlList.add("ASCII");
        sqlList.add("UPDATE");
        sqlList.add("SELECT");
        sqlList.add("'");
        sqlList.add("SUBSTR(");
        sqlList.add("COUNT(");
        sqlList.add(" OR ");
        sqlList.add(" AND ");
        sqlList.add("DROP");
        sqlList.add("EXECUTE");
        sqlList.add("EXEC");
        sqlList.add("TRUNCATE");
        sqlList.add("INTO");
        sqlList.add("DECLARE");
        sqlList.add("MASTER");
    }

    /**
     * 对常见的sql注入攻击进行拦截
     *
     * @param sInput 输入参数
     * @return true 表示参数不存在SQL注入风险
     * false 表示参数存在SQL注入风险
     */
    public static Boolean sqlStrFilter(String sInput) {
        if (sInput == null || sInput.trim().length() == 0) {
            return false;
        }
        sInput = sInput.toUpperCase();
        for (String str :
                sqlList) {
            if (sInput.contains(str)) {
                log.error("该参数怎么SQL注入风险：sInput={}", sInput);
                return false;
            }
        }
        log.info("通过sql检测");
        return true;
    }

    /**
     * 对非法字符进行检测
     *
     * @param sInput 输入的参数
     * @return true 表示参数不包含非法字符
     * false 表示参数包含非法字符
     */
    public static Boolean isIllegalStr(String sInput) {
        if (sInput == null || sInput.trim().length() == 0) {
            return false;
        }
        sInput = sInput.trim();
        Pattern compile = Pattern.compile(REGX, Pattern.CASE_INSENSITIVE);
        Matcher matcher = compile.matcher(sInput);
        log.info("通过字符串检测");
        return matcher.find();
    }


}
